/**************************************************************************//**
 * @item     CosyOS-III Port
 * @file     port_8051.h
 * @brief    8051 Core Port File
 * @author   迟凯峰
 * @version  V2.0.1
 * @date     2025.08.19
 ******************************************************************************/

#ifndef __PORT_8051_H
#define __PORT_8051_H

/* INCLUDE */
#include <intrins.h>
#include "os_base.h"
#include "os_def.h"
#include "syscfg.h"
#include "mcucfg_8051.h"
#include SYSCFG_STANDARDHEAD


/* Memory */
#define _SYS_MEM_    data
#define _CODE_MEM_   code
#define _CONST_MEM_  code
#define _STACK_MEM_  idata
#define _XDATA_MEM_  xdata
#define _STATIC_MEM_ xdata
#ifndef _MALLOC_MEM_
#define _MALLOC_MEM_ xdata
#endif
#define _OBJ_MEM_    xdata
/*
 * 用户自定义内存
 * 用户可自定义下方的内存，以寻求在性能和资源之间取得平衡。默认为未定义，由内存MODEL决定。
 * 在 os_var.c、os_var.h 中，用户也可逐个查看及调整对应定义内存的变量，以实现极致的优化。
 */
#define _RTC_MEM_    /* 软件RTC相关系统变量的内存 */
#define _DEBUG_MEM_  /* DEBUG相关系统变量的内存 */


/* Register */
#define _SYS_REG_    _SYS_MEM_


/* Typedef */
#define m_boolvoid_tf (s_boolvoid_tf)
#ifndef bool
typedef s_u8_t bool;
#endif
typedef bit      m_bit_t;
typedef s_u8_t   m_sp_t;
typedef s_u16_t  m_tick_t;
typedef s_u16_t  m_pc_t;
typedef s_u8_t   m_tqcount_t;
typedef s_u8_t   m_fetion_t;
typedef s_u32_t  m_group_t;
#if (MCUCFG_XBPSTACK == __ENABLED__)
typedef s_u16_t  m_stacksize_t;
#else
typedef s_u8_t   m_stacksize_t;
#endif
typedef s_u8_t   m_stacklen_t;
#if (SYSCFG_SYSTICK_CYCLE > 1000000UL / 65536)
typedef s_u16_t  m_rtccount_t;
#else
typedef s_u32_t  m_rtccount_t;
#endif


/* Extern */
extern  bit      m_sign_fifo_0_0;
extern  s_u8_t   mPendSV_FIFO_DepthMAX;
extern  void     mx_disable_irq(void);
extern  void     mx_resume_irq (void);
extern  bool     mPendSV_FIFOLoader (s_u16_t sv);
extern  void     mPendSV_FIFOHandler(void);


/* CMSIS */
#ifndef __WEAK
#define __WEAK
#endif
#ifndef __NOP
#define __NOP _nop_
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE static
#endif
#ifndef __NOINLINE
#define __NOINLINE
#endif
#define __UNUSED(X) X = X


/* CONST & ATTRIBUTE */
#define MCUCFG_ISA                __MCS_51__
#define MCUCFG_PCLEN              2
#if (MCUCFG_TASK_VECTOR)
#define MCUCFG_TASK_ATTRIBUTE     interrupt MCUCFG_TASK_VECTOR using MCUCFG_TASK_REGBANK
#else
#define MCUCFG_TASK_ATTRIBUTE
#endif
#if (MCUCFG_TASK_REGBANK != MCUCFG_OSIT_REGBANK)
#define MCUCFG_OSIT_ATTRIBUTE     using MCUCFG_OSIT_REGBANK
#else
#define MCUCFG_OSIT_ATTRIBUTE
#endif
#define MCUCFG_SYSTICK_ATTRIBUTE  interrupt 1 MCUCFG_OSIT_ATTRIBUTE
#define MCUCFG_TERNARYMASK        false;

#define MCUCFG_STACK_ALIGN
#define MCUCFG_TASKSTACK_REALLOC  __ENABLED__
/** 1: \PUSH {PC,A,B,DPH,DPL,PSW}, \SAVE {TASK-REGBANK:R0-R7,[USERREG(ASM)],[?C_XBP]} */
/** 2: \PUSH {PC,A,B,DPH,DPL,PSW,[USERREG(ASM)]}, \SAVE {TASK-REGBANK:R0-R7,[?C_XBP]} */
/** 3: \PUSH {PC,A,B,DPH,DPL,PSW,TASK-REGBANK:R0-R7}, \SAVE {[USERREG(ASM)],[?C_XBP]} */
/** 4: \PUSH {PC,A,B,DPH,DPL,PSW,TASK-REGBANK:R0-R7,[USERREG(ASM)]}, \SAVE {[?C_XBP]} */
#define MCUCFG_BASICSTACKSIZE     (15 + MCUCFG_USERREGSIZE + (MCUCFG_XBPSTACK == __ENABLED__ ? 2 : 0))


/* TaskNode */
#define mTaskNode_Head_           m_stacksize_t stacklen;
#define mTaskNode_Tail_           mUserReg_DEFc_


/* SysTick */
#define MCUCFG_SYSTICK_COUNTMODE    3                /*!< 计数方式，3：从重装载值向上计数至零溢出 */
#define MCUCFG_SYSTICK_LIMITVALUE  (1UL << 16)       /*!< 极限值 */
#define MCUCFG_SYSTICK_CURRVALUE  ((TH0 << 8) | TL0) /*!< 当前值寄存器 */
#define MCUCFG_SYSTICK_CLKDIV     ((MCUCFG_SYSCLKHZ / 1000UL * SYSCFG_SYSTICK_CYCLE <= MCUCFG_SYSTICK_MAXVALUE * 1000UL) ? 1 : 12)
#define MCUCFG_SYSTICK_COUNT1CYC  ((MCUCFG_SYSCLKHZ / 1000UL * SYSCFG_SYSTICK_CYCLE) / MCUCFG_SYSTICK_CLKDIV   / 1000UL)
#define MCUCFG_SYSTICK_LOADVALUE   (MCUCFG_SYSTICK_LIMITVALUE - MCUCFG_SYSTICK_COUNT1CYC)
#define MCUCFG_SYSTICK_MAXVALUE     MCUCFG_SYSTICK_LIMITVALUE
#define MCUCFG_SYSTICK_MINVALUE     MCUCFG_SYSTICK_LOADVALUE
#if (MCUCFG_SYSTICK_COUNT1CYC > (MCUCFG_SYSTICK_LIMITVALUE - 1))
#error 系统滴答定时器溢出。
#endif
#define mSysTick_INIT() \
do{ \
	AUXR = MCUCFG_SYSTICK_CLKDIV == 1 ? AUXR | 0x80 : AUXR &~0x80; \
	TMOD &= 0xF0; \
	TL0 = (s_u8_t)(MCUCFG_SYSTICK_LOADVALUE); \
	TH0 = (s_u8_t)(MCUCFG_SYSTICK_LOADVALUE >> 8); \
	TR0 = 1; \
}while(false)
#define mSysTick_Disable()  ET0 = 0
#define mSysTick_Enable()   ET0 = 1
#define mSysTick_Clear()


/* 内核锁 */
#define mSysIRQ_Disable() \
do{ \
	mPendSV_Disable(); \
	mSysTick_Disable(); \
}while(false)

#define mSysIRQ_Enable() \
do{ \
	mSysTick_Enable(); \
	mPendSV_Enable(); \
}while(false)


/* CosyOS初始化 */
#define mCosyOS_INIT() \
do{ \
	s_init_mempool((void _MALLOC_MEM_ *)MCUCFG_MALLOCMEMBPTR, MCUCFG_MALLOCMEMSIZE); \
	OS_NOP(1); \
	mSysTick_INIT(); \
	mSysIRQ_Enable(); \
	EA = 1; \
}while(false)


/* CosyOS低功耗 */
#define mCosyOS_IDLE() \
do{ \
	PCON |= 0x01; \
	OS_NOP(4); \
}while(false)


/* 中断挂起服务_FIFO */
#if (SYSCFG_PENDSVFIFO_MONITOR == __ENABLED__)
#define mPendSV_FIFOLoad() \
do{ \
	if(!mPendSV_FIFOLoader((s_u16_t)&u_psv)) mPendSV_Set(); \
	else s_fault.overflow_pendsvfifo = true; \
}while(false)
#else
#define mPendSV_FIFOLoad() \
do{ \
	if(!mPendSV_FIFOLoader((s_u16_t)&u_psv)) mPendSV_Set(); \
}while(false)
#endif

#define mPendSV_FIFOHandle() \
	if(!m_sign_fifo_0_0) mPendSV_FIFOHandler()


/* 事件标志组-中断中写多标志位 */
#define miWriteFlagBits() \
	static bit u_f = false; \
	if(!u_f){ \
		u_f = true


/* 任务栈 */
#if (MCUCFG_XBPSTACK == __ENABLED__)
#define mXBP_INIT() \
	*(s_u16_t *)(node_news->bsp + 15 + MCUCFG_USERREGSIZE) \
	  = node_news->bsp + node_news->stacksize
#else
#define mXBP_INIT()
#endif

#define mTaskStack_INIT() \
do{ \
	node_news->stacklen = ( \
	   (MCUCFG_TASK_REGBANK == MCUCFG_OSIT_REGBANK ? 15 : 7) \
	 + (MCUCFG_USERREGCONFIG == 1 ? MCUCFG_USERREGSIZE : 0) \
	); \
	*(s_u16_t *)node_news->bsp = ( \
	   ((s_u16_t)s_task_starter->entry << 8) \
	 | ((s_u16_t)s_task_starter->entry >> 8) \
	); \
	*(s_u8_t *)(node_news->bsp + 7 - 1) = MCUCFG_TASK_REGBANK * 8; \
	mUserReg_INITa(); \
	mXBP_INIT(); \
	mUserReg_INITc(); \
}while(false)

#define mTaskStack_LEN()


/* 全局临界区 */
#define mxDisableIRQ()  mx_disable_irq()
#define mxResumeIRQ()   mx_resume_irq()


#endif
